package com.tarena.service;

import com.google.gson.Gson;
import com.tarena.pojo.Message;
import com.tarena.pojo.MessageType;
import com.tarena.pojo.User;
import com.tarena.utils.ServerMessageQueue;

import java.lang.management.MemoryType;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/*
* 该类主要用于管理服务端的各个线程对象，实现添加，获取等功能
* 以实现单聊和群聊
* */
public class ManageConnectServerList {
    //设置集合对象，用于保存服务端的线程对象
    private static HashMap<User,ServerSocketThread> ss = new HashMap<>();
    private static HashMap<User,HashMap<User,ServerMessageQueue>> usq = new HashMap<>();
    private static Gson gson = new Gson();
    /*返回集合对象*/
    public static HashMap<User, ServerSocketThread> getSs() {
        return ss;
    }

//    1.按传入的getter来获取里层层hashmap(消息队列集合)
    public static HashMap<User,ServerMessageQueue> getUserOffLineMsg(User getter){
        return usq.get(getter);
    }
//    2.删除离线消息
    public static void removeOffLineMsg(User getter){
        usq.remove(getter);
    }
//    3.添加离线消息到hashmap
    public static void addOffLineToMap(User getter,User sender,String msg){
//        判断当前hashmap是否存在getter
//        todo 代码需要整合
        HashMap<User, ServerMessageQueue> us = getUserOffLineMsg(getter);
        if(us==null){
            us = new HashMap<>();
            ServerMessageQueue smq = new ServerMessageQueue();/*new了一个队列*/
            smq.addMsgToQUeue(msg);/*将消息加入到队列里面*/
            us.put(sender,smq);
            usq.put(getter,us);
        }else if(us.get(sender)==null){
            ServerMessageQueue smq = new ServerMessageQueue();/*new了一个队列*/
            smq.addMsgToQUeue(msg);/*将消息加入到队列里面*/
            us.put(sender,smq);
            usq.put(getter,us);
        }else{
           ServerMessageQueue smq= us.get(sender);
           smq.addMsgToQUeue(msg);
            us.put(sender,smq);
            usq.put(getter,us);
        }
    }

    /*添加线程对象到hashmap中*/
    public static void addThreadToMap(User user,ServerSocketThread sst){
        ss.put(user,sst);
        System.out.println(user.getUsername()+"已添加到服务器"+",当前已有"+ss.size()+"个用户");
        /*获取在线用户(刷新朋友列表)*/
        notiClientRefFriends(user);
//        如果有离线消息，则发送给当前登陆的用户
        // TODO: 2021/7/14 可以优化整合
        if(usq.get(user)!=null && usq.get(user).size()>0){
            sendOffLineMsgToUser(user,sst);
        }
    }
    /*可以根据用户对象返回该用户对应的线程对象*/
    public static ServerSocketThread getThreadFromMap(User user) {
        return ss.get(user);
    }
    /*移除功能*/
        public static void removeThreadFromMap(User user){
         ss.remove(user);
        }
        /*获取所以的在线用户*/
    public static Set<User> getAllonlineUser(){
       /* Set<User> users = ss.keySet();
        return users;*/
        return ss.keySet();
    }
    public static void notiClientRefFriends(User cuurrentUser){
        Set<Map.Entry<User, ServerSocketThread>> entries = ss.entrySet();
        for (Map.Entry<User, ServerSocketThread> entry : entries) {
            if(entry.getKey().equals(cuurrentUser)){
                /*遍历到的就是当前的用户，所以不刷新*/
                continue;
            }
            ServerSocketThread sst= entry.getValue();
            sst.reFriendsList(MessageType.MESSAGE_GET_ONLINE_FRIENDS);
        }
    }

    /*判断用户是否已经登录*/
    public static boolean isUserLogined(User loginUser){
        boolean result = false;
        Set<Map.Entry<User, ServerSocketThread>> entries = ss.entrySet();
        for (Map.Entry<User, ServerSocketThread> entry : entries) {
            User key=entry.getKey();
            if(key.equals(loginUser)){
                result= true;
            }
        }
        return result;
    }
    public static void sendMsgToUser(Message message){
        boolean flag = false;
        Set<Map.Entry<User, ServerSocketThread>> entries = ss.entrySet();
        for (Map.Entry<User, ServerSocketThread> entry : entries) {
            User key=entry.getKey();
            if(key.equals(message.getGetter())){
                /*发送信息到目标用户客户端*/
                ServerSocketThread value = entry.getValue();
                value.sendMsg(message);
                flag = true;
                break;
            }
        }
//        该目标用户尚未登录
        if(!flag){
            addOffLineToMap(message.getGetter(),message.getSender(), message.getContent());
       }
    }
//    发送离线消息到指定登陆的用户
    public static void sendOffLineMsgToUser(User getter,ServerSocketThread sst){
        HashMap<User, ServerMessageQueue> map = getUserOffLineMsg(getter);/*所以的离线消息*/
        Set<Map.Entry<User, ServerMessageQueue>> entries = map.entrySet();
        Message message = new Message();
        for (Map.Entry<User, ServerMessageQueue> entry : entries) {
            message.setGetter(getter);
            message.setSender(entry.getKey());
            String s = gson.toJson(entry.getValue().getMsgQueue());
            message.setContent(s);
            message.setMagType(MessageType.MESSAGE_OFFLINE_MES);
            sst.sendMsg(message);
        }
    }

}
